const Base = require('./base.js');
const request = require('request');
module.exports = class extends Base {
    indexAction() {
        return this.display();
    }

    async operatorAction() {
        // const data = await this.model('operator_device').select();
        // console.log("90621200001",data)
        return this.display();
    }

    async getOperatorAction() {
        let db = this.model('operator_device');
        let result = await db.page(this.get("page")).countSelect();
        return this.jsonPage(result);
    }

    async enabledAction() {
        let data = this.post();
        let model = this.model('operator_device');
        let success = await model.where({id: data.id}).update({enable: data.enabled});
        return this.json(success);
    }

    async editOperatorAction() {
        let data = this.post();
        let result = false;
        let db = this.model('operator_device');

        try {
            let insertId = await db.where({id: data.id}).update(data);
            result = insertId > 0;
        } catch (ex) {
            result = false;
        } finally {
            this.ctx.body = {
                success: result
            };
        }
    }

    async addOperatorAction() {
        let userinfo = this.session('userinfo');
        let db = this.model('operator_device');
        let data = this.post();
        data.created_by_id = 7;
        data.date_created = new Date().format("yyyy-MM-dd hh:mm:ss");
        let insertId = await db.add(data);
        this.ctx.body = {
            success: insertId > 0
        };
    }

    async findAction() {
        let result;
        let url = this.ctx.url;
        let db = this.model('operator_device');
        let resultObj = this.urlParse(url);
        for (let key in resultObj) {
            if (key == 'limit' || key == 'page')
                delete  resultObj[key];
        }
        let newObj = JSON.parse(JSON.stringify(resultObj));
        let json = {};
        for (let key in newObj) {
            json[key] = ['like', [`%${newObj[key]}%`]];
        }
        result = await db.where(json).page(this.get("page"), this.get("limit")).countSelect();
        result.code = 0;
        result.msg = "";

        return this.ctx.body = result;
    }

    async getBelongAction() {
        let model = this.model('operator_device');
        let data = await model.field('belong_operator,id').select();

        return this.ctx.body = data;
    }

    resAction() {
        return this.display();
    }

    ipOpenAction() {
        return this.display();
    }

    async getIpAction() {
        let result;
        let url = this.ctx.url;
        let db = this.model('external_ip');
        let resultObj = this.urlParse(url);
        for (let key in resultObj) {
            if (key == 'limit' || key == 'page')
                delete  resultObj[key];
        }
        let newObj = JSON.parse(JSON.stringify(resultObj));
        let json = {};
        for (let key in newObj) {
            json[key] = ['like', [`%${newObj[key]}%`]];
        }
        result = await db.where(json).page(this.get("page"), this.get("limit")).countSelect();
        result.code = 0;
        result.msg = "";

        return this.ctx.body = result;
    }

    async editIpAction() {
        let data = this.post();
        let result = false;
        let db = this.model('external_ip');
        let arr = ['tb_location b ON location_id=b.id'];
        try {
            let insertId = await db.join(arr).where({id: data.id}).update(data);
            result = insertId > 0;
        } catch (ex) {
            result = false;
        } finally {
            this.ctx.body = {
                success: result
            };
        }
    }

    instancesAction() {
        return this.display();
    }

    appManageAction() {
        return this.display();
    }

    dataOperateAction() {
        return this.display();
    }

    async getTreeAction() {
        let db = this.model('master');
        let data = await db.where({enabled: 1}).select();
        let arr = [];
        let json = {};
        for (let i = 0; i < data.length; i++) {
            json.id = data[i].id;
            json.text = data[i].master_name;
            arr.push(json);
            json = {};            //初始化
        }
        return this.jsonPage(arr);
    }

    async nodeInfoAction() {
        let db = this.model('ip');
        let postData = this.get();
        let data = await db.where({
            master_id: postData.id
        }).page(this.get("page"), this.get("limit")).countSelect()
        return this.jsonPage(data);
    }

    async editAction() {
        let db = this.model('master');
        let data = this.post();
        let success = await db.where({id: data.id}).update(data);
        return this.json(success);
    }

    async getCountryAction() {
        let db = this.model('country');
        let countryList = await db.select();
        return this.json(countryList);
    }

    async getPingAction() {
        let db = this.model('ping');
        let pingList = await db.select();
        return this.json(pingList);
    }

    async getIpInfoAction() {
        let db = this.model('ip');
        let ipList = await db.where(this.post().id).find();
        return this.json(ipList);
    }

    async createIpAction() {
        let db = this.model('ip');
        let data = this.post();
        let location = await this.model('location').where({
            location_name: data.location_id,
            zone: data.zone,
            area: data.area
        }).find();
        data.ping_id = data['ping_id[]'];
        data.location_id = location.id;
        if (data.country_id == '') {
            data.country_id = null;
        }
        delete data['ping_id[]'];
        if (data.accelerate_type == "EN") {
            data.acceleration = 2;
        } else if (data.accelerate_type == "CN") {
            data.acceleration = 1;
        } else {
            data.acceleration = 0;
        }
        try {
            let ipId = await db.add(data);      //获得ipId
            if (ipId > 0) {
                let count = 0;
                if (data.ping_id instanceof Array) {
                    for (let i = 0; i < data.ping_id.length; i++) {
                        let pingId = await this.model('ping_ip').add({ip_id: ipId, ping_id: data.ping_id[i]});
                        if (pingId > 0) {
                            count++;
                        }
                    }
                } else {
                    let pingId = await this.model('ping_ip').add({ip_id: ipId, ping_id: data.ping_id});
                    if (pingId > 0) {
                        return this.fail('1', '添加ip成功！');
                    }
                }
                if (count == data.ping_id.length) {
                    return this.fail('1', '添加ip成功！');
                }

            }
        } catch (e) {
            return this.fail('500', '添加ip错误！');
        }
        return this.fail('500', '添加ip错误！');
    }

    async deleteAction() {
        let db = this.model('master');
        let data = this.post();
        let success = await db.where({id: data.id}).update({enabled: 1});
        return this.json(success);
    }

    async addAction() {
        let db = this.model('master');
        let data = this.post();
        let master = await db.where({master_name: data.master_name, enabled: 1}).find();

        try {
            if (typeof (master.master_name) == 'undefined') {
                let success = await db.add(data);
                return this.json(success);
            }
            return this.json('0');
        } catch (e) {
            return this.json('0');
        }
    }

    async initMasterAction() {
        let data = this.post();
        let whereStr = `tb_ip.enabled =1 and master_id = ${data.master_id}`;
        let db = this.model('ip');
        let ipList = await db.where(whereStr).select();
        for (let i = 0; i < ipList.length; i++) {
            if (ipList[i].ping_ip.length == 0) {
                return this.fail('0', '请把每个ip的ping地址填写完整再进行初始化')
            }

        }
        if (ipList.length > 0) {
            let index = Math.floor((Math.random() * ipList.length) + 0);
            let initializeAddress = "http://" + ipList[index].ip_address + ":1080/master/init";    //拼接字符
            let json = JSON.stringify(await this.getChildNode(data.master_id));
            let postData = {};
            postData.json = json;
            postData.url = initializeAddress;
            let result = await this.sendRequest(postData);
            if (result.code == 0) {
                result = result.children_resp;
                for (let i = 0; i < result.length; i++) {
                    try {
                        let ipRow = await db.where({id: result[i].id}).update({state: [result[i].code]});        //修改ip状态
                        if (ipRow <= 0) {
                            return this.fail('5', '线路状态修改失败！请重试！');
                        }
                    } catch (e) {
                        return this.fail('6', '线路状态修改失败！请重试！');
                    }
                }
                let master = await this.model('master').where({id: data.master_id}).find();
                let count = 1;
                if (typeof (master.init_num) != 'undefined') {
                    count = master.init_num + 1;
                }
                let masterResult = await this.model('master').where({id: data.master_id}).update({init_num: count});//master初始化次数+1
                if (masterResult <= 0) {
                    return this.fail('7', '初始化失败！master状态修改失败！');
                }

            } else {
                return this.fail('4', '初始化失败！');
            }

        } else {
            return this.fail('2', '没有可用ip了！')
        }
        return this.fail('1', '初始化成功！')
    }

    sendRequest(data) {
        return new Promise((resolve, reject) => {
            request({
                url: data.url,
                method: 'POST',
                json: true,
                headers: {
                    "content-type": "application/x-www-form-urlencoded",
                },
                body: data.json
            }, (error, response, body) => {
                if (typeof (body) != 'undefined') {
                    resolve(body);
                } else {
                    let respJson = {};
                    respJson.code = 20;
                    respJson.msg = 'timeout connection !';
                    resolve(respJson);
                }
            });
        });
    }


    async getChildNode(data) {
        let master = await this.model('master').where({id: data}).find();
        let ipStr = `master_id = ${data} and tb_ip.enabled = 1 `;
        let ipList = await this.model('ip').where(ipStr).order('ip_address desc').select();
        let fatherMap = {};
        let childrenList = [];
        let ipMap = {};
        let pingArray = [];

        for (let i = 0; i < ipList.length; i++) {
            ipMap = {};
            ipMap.port = ipList[i].port;
            ipMap.ip = ipList[i].ip_address;
            ipMap.inside_ip = ipList[i].inside_ip;
            ipMap.id = String(ipList[i].id);
            ipMap.ip_type = String(ipList[i].ip_type);
            ipMap.region = ipList[i].region;
            ipMap.provider = ipList[i].provider;
            ipMap.top_limit = ipList[i].top_limit;
            ipMap.mode = ipList[i].ip_model;
            for (let j = 0; j < ipList[i].ping_ip.length; j++) {
                let ping = await this.model('ping').where({id: ipList[i].ping_ip[j].ping_id}).find();
                pingArray.push(ping.ping_name);
            }
            ipMap.ping = pingArray;
            pingArray = [];   //初始化
            childrenList.push(ipMap)
        }

        fatherMap.id = String(master.id);
        fatherMap.text = master.master_name;
        fatherMap.report_frequency = master.report_frequency;
        fatherMap.keepliveurl = master.keep_live_url;
        fatherMap.bindlive = master.bind_live;
        fatherMap.children = childrenList;
        fatherMap.death_url = ipList[0].location.death_url;
        return fatherMap;
    }

    async stopMasterAction() {
        let data = this.post();
        let whereStr = ` master_id = ${data.master_id}`;
        let db = this.model('ip');
        let ipList = await db.where(whereStr).select();
        let count = 0;   //记录未初始化的ip数量

        // if (typeof (data.master_id) == 'undefined') {
        //     return this.fail('2', '无效的masterId');
        // }
        if (think.isEmpty(data.master_id)) {
            return this.fail('2', '无效的masterId');
        }
        for (let i = 0; i < ipList.length; i++) {
            if (ipList[i].state == 0 || ipList[i].state == 1) {
                count++;
            }
        }

        if (count == 0) {
            return this.fail('0', '该master下的所有ip都未初始化！无需关闭！')
        }

        let stopAddress;
        let sendMap = {};
        let dataMap = {};
        let masterState = [];
        for (let i = 0; i < ipList.length; i++) {
            sendMap.ip_id = String(ipList[i].id);
            stopAddress = "http://" + ipList[i].ip_address + ":1080/fn/stop";
            dataMap.url = stopAddress;
            dataMap.json = JSON.stringify(sendMap);
            let requestResult = await this.sendRequest(dataMap);
            if (requestResult.code == 0) {
                let resultCount = await db.where({id: ipList[i].id}).update({state: 2});
                if (resultCount > 0) {
                    masterState.push(0);
                } else {
                    masterState.push(1);
                }
            } else {
                masterState.push(1);
            }
        }

        for (let i = 0; i < masterState.length; i++) {
            if (masterState[i] != 0) {
                return this.fail('3', 'master关闭失败，部分ip关闭失败');
            }
        }
        return this.fail('1', '关闭成功！')
    }

    async openAction() {
        let data = this.post();
        let db = this.model('ip');
        let ipList = await db.where({id: data.id}).find();

        if (ipList.state == '2' || ipList.state == '3' || ipList.state == '4') {
            let stopAddress;
            let sendMap = {};
            let dataMap = {};
            sendMap.ip_id = String(ipList.id);
            stopAddress = "http://" + ipList.ip_address + ":1080/fn/open";
            dataMap.url = stopAddress;
            dataMap.json = JSON.stringify(sendMap);
            let requestResult = await this.sendRequest(dataMap);
            if (requestResult.code == 0) {
                let success = await db.where({id: ipList.id}).update({state: requestResult.code, enabled: 1});
                if (success > 0)
                    return this.fail('1', '线路启用成功！');
            }
        } else {
            let success = await db.where({id: ipList.id}).update({enabled: 1});
            if (success > 0)
                return this.fail('1', '线路启用成功！');
        }
        return this.fail('0', '线路启用失败，请重试！');
    }

    async stopAction() {
        let data = this.post();
        let db = this.model('ip');
        let ipList = await db.where({id: data.id}).find();
        if (ipList.state == '0' || ipList.state == '1') {
            let stopAddress;
            let sendMap = {};
            let dataMap = {};
            sendMap.ip_id = String(ipList.id);
            stopAddress = "http://" + ipList.ip_address + ":1080/fn/stop";
            dataMap.url = stopAddress;
            dataMap.json = JSON.stringify(sendMap);
            let requestResult = await this.sendRequest(dataMap);
            if (requestResult.code == 0) {
                let success = await db.where({id: ipList.id}).update({state: requestResult.code, enabled: 0});
                if (success > 0)
                    return this.fail('1', '线路关闭成功！');
            }
        } else {
            let success = await db.where({id: ipList.id}).update({state: 2, enabled: 0});
            if (success > 0)
                return this.fail('1', '线路关闭成功！');
        }
        return this.fail('0', '线路关闭失败，请重试！');
    }

    async editLineStatusAction() {
        let data = this.post();
        let db = this.model('ip');
        let success = await db.where({id: data.id}).update({line_status: data.line_status});     //修改线路的可用状态为不可用
        if (success > 0) {
            return this.fail('1', '线路状态修改成功！');
        }
        return this.fail('0', '线路状态修改失败！');
    }

    async deleteAction() {
        let data = this.post();
        let db = this.model('ip');
        let ipList = await db.where({id: data.id}).find();

        if (ipList.state != 0 || ipList.state != 1) {
            let success = await db.where({id: ipList.id}).update({enabled: 0});     //修改线路的可用状态为不可用
            if (success > 0) {
                return this.fail('1', '线路关闭成功！');
            }
            return this.fail('0', '线路关闭失败！');
        }

        let stopAddress;
        let sendMap = {};
        let dataMap = {};
        sendMap.ip_id = String(ipList.id);
        stopAddress = "http://" + ipList.ip_address + ":1080/fn/stop";
        dataMap.url = stopAddress;
        dataMap.json = JSON.stringify(sendMap);
        let requestResult = await this.sendRequest(dataMap);
        if (requestResult.code == 0) {
            let success = await db.where({id: ipList.id}).delete();
            if (success > 0) {
                return this.fail('1', '线路关闭成功！');
            }
            return this.fail('2', '线路关闭失败！,请重试！');
        }
        return this.fail('0', '线路关闭失败，连接超时请重试！');
    }


    async getLocationAction() {
        let db = this.model('location');
        let ipList = await db.group('location_name').select();
        this.ctx.body = {ipList};
    }

    async getCloudRegionAction() {
        let data = this.post();
        let db = this.model('location');
        let ipList = await db.where({location_name: data.name}).select();
        this.ctx.body = {ipList};
    }

    async getZoonAction() {
        let data = this.post();
        let db = this.model('location');
        let ipList = await db.where({area: data.name}).select();
        this.ctx.body = {ipList};
    }

    async getZoneAllAction() {
        let db = this.model('location');
        let ipList = await db.select();
        this.ctx.body = {ipList};
    }

    async editIpInfoAction() {
        let db = this.model('ip');
        let ping_ip = this.model('ping_ip');
        let data = this.post();
        if (data.country_id == '') {
            data.country_id = null;
        }
        let location = await this.model('location').where({
            location_name: data.location_id,
            zone: data.zone,
            area: data.area
        }).find();
        let ping_id = data['ping_id[]'];

        delete  data['ping_id[]'];
        delete  data['area'];
        delete  data['zone'];
        data.location_id = location.id;
        let ipResult = await db.where({id: data.id}).update(data);
        if (ipResult > 0) {
            let delResult = await ping_ip.where({ip_id: data.id}).delete();
            if (ping_id != null) {
                if (ping_id instanceof Array) {
                    for (let i = 0; i < ping_id.length; i++) {
                        let pingResult = await ping_ip.add({ip_id: data.id, ping_id: ping_id[i]});
                        if (pingResult < 1) {
                            return this.fail(pingResult, '修改ip失败！');
                        }
                    }
                } else {
                    let pingResult = await ping_ip.add({ip_id: data.id, ping_id: ping_id});
                    if (pingResult < 1) {
                        return this.fail(pingResult, '修改ip失败！');
                    }
                }
            }
        }
        return this.fail('1', '修改成功！');
    }

    async getMasterAction() {
        let data = this.post();
        let db = this.model('master');
        let masterList = await db.where({id: data.master_id}).find();
        this.ctx.body = {masterList};
    }

    async getInitMasterNumberAction() {
        let flag = 0
        let num = 0
        let data = this.post();
        let arr = 'tb_master b on master_id = b.id';
        let whereStr = `tb_ip.enabled =0 and master_id = ${data.master_id}`;
        let db = this.model('ip');
        let result = await db.join(arr).where(whereStr).select();

        for (let i = 0; i < result.length; i++) {
            if (result[i].state == 3 && result.length != 0) {
                result = 0;
                break
            } else if (result.length != 0) {
                if (result[i].state != 2 && result[i].state != 3 && result[i].state != 4) {
                    result = 1
                } else {
                    result = 0
                }
            }
            if (result[i].state == 2 || result[i].state == 3 || result[i].state == 4) {
                num++
            }
            //如果计数num等于该路线list的总长度，则该master下的所有路线全部关闭或者失败
            if (num == result.length) {
                result = 2
            }
        }
        return num;
    }

    async historyVersionAction() {
        return this.display();
    }

    async fileVersionListAction() {
        return this.display();
    }

};
